/* usbn960x.c
* Copyright (C) 2005  Benedikt Sauter
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <avr/interrupt.h>
#include "usbn2mc.h"
#include "uart.h"

//*******************************************************************
// add own vendor requests          
// ********************************************************************

// decode your own vendor requests

void
USBNDecodeVendorRequest (DeviceRequest * req)
{
#if 0
  //SendHex(req->bRequest);       // decode request code
  SendHex (req->wLength);	// decode request code
  USBNWrite (RXC0, RX_EN);
  USBNRead (RXD0);
  USBNRead (RXD0);

  //USBNWrite(TXC0,FLUSH);
  //USBNWrite(TXD0,0x24);
  //USBNWrite(TXD0,0x25);
#endif
}


void
USBNDecodeClassRequest (DeviceRequest * req)
{
#if 0
  //SendHex(req->bRequest);       // decode request code
  SendHex (req->wLength);	// decode request code
  USBNWrite (RXC0, RX_EN);
  USBNRead (RXD0);
  USBNRead (RXD0);
#endif
}



// ********************************************************************
// This subroutine handles the communication with usbn9604          
// ********************************************************************


// Read data from usbn96x register

void
USBNInitMC (void)
{
  // interrupt on INT4 pin falling edge (atmega128)
  //EICRB = (0 << ISC41) | (1 << ISC40);
  // interrupts on!
  //EIMSK = (1 << INT4);		// allow extern irq4

  /*
  EICRB = (1 << ISC40);
  EIMSK = (1 << INT4);
  */

  USB_CTRL_DDR |= (1 << PF_A0) | (1 << PF_RD) | (1 << PF_WR);	// output (a0,rd,wr)
  //USB_CTRL_PORT |= ((1 << PF_RD) | (1 << PF_WR) & ~(PF_A0));
  USB_CTRL_PORT |= ((1 << PF_RD) | (1 << PF_WR));
  USB_CS_DDR |= (1 << PF_CS);
  USB_CS_PORT |= (1 << PF_CS);

  //sei ();
}


unsigned char
USBNRead (unsigned char Adr)
{
  USB_DATA_DDR = 0xff;		// set for output
  USB_DATA_OUT = Adr;		// load address

  USB_CS_PORT ^= (1 << PF_CS);
  USB_CTRL_PORT ^= (1 << PF_WR) | (1 << PF_A0);	// strobe the CS, WR, and A0 pins
  USB_CS_PORT ^= (1 << PF_CS);
  USB_CTRL_PORT ^= (1 << PF_WR) | (1 << PF_A0);	// strobe the CS, WR, and A0 pins
//      USB_CS_PORT ^=(1<<PF_CS);       
//      USB_CTRL_PORT ^= (1<<PF_WR) |(1<<PF_A0);
  asm ("nop");			// pause for data to get to bus
  USB_DATA_DDR = 0x00;		// set PortD for input
  return (USBNBurstRead ());	// get data off the bus
}


unsigned char
USBNBurstRead (void)
{
  unsigned char result;

  USB_CS_PORT ^= (1 << PF_CS);
  USB_CTRL_PORT ^= (1 << PF_RD);

  asm ("nop");			// pause for data to get to bus
  asm ("nop");
  result = USB_DATA_IN;
  USB_CS_PORT ^= (1 << PF_CS);
  USB_CTRL_PORT ^= (1 << PF_RD);
  return result;
}


// Write data to usbn96x register
void
USBNWrite (unsigned char Adr, unsigned char Data)
{
  USB_DATA_OUT = Adr;		// put the address on the bus
  USB_DATA_DDR = 0xff;		// set for output
  USB_CS_PORT ^= (1 << PF_CS);
  USB_CTRL_PORT ^= (1 << PF_WR) | (1 << PF_A0);
  USB_CS_PORT ^= (1 << PF_CS);
  USB_CTRL_PORT ^= (1 << PF_WR) | (1 << PF_A0);
  USBNBurstWrite (Data);
}


void
USBNBurstWrite (unsigned char Data)
{
  USB_DATA_OUT = Data;		// put data on the bus
  USB_CS_PORT ^= (1 << PF_CS);
  USB_CTRL_PORT ^= (1 << PF_WR);
  USB_CS_PORT ^= (1 << PF_CS);
  USB_CTRL_PORT ^= (1 << PF_WR);
}



void
USBNDebug (char *msg)
{
//  UARTWrite (msg);
}
